// 定义Supermap模型管理类
export class SupermapModel {
  constructor(viewer) {
    this.viewer = viewer;
    this.models = []; // 存储所有加载的模型
    this.preloadMode = false; // 预加载模式标志
    this.tunnelEntities = []; // 存储隧道标记实体
  }

  /**
   * 设置预加载模式
   * @param {boolean} value 是否开启预加载模式
   */
  setPreloadMode(value) {
    this.preloadMode = !!value;
    console.log(`预加载模式已${this.preloadMode ? '开启' : '关闭'}`);
  }

  /**
   * 加载3D模型
   * @param {string} url 模型URL
   * @param {Array} matrix 模型变换矩阵
   * @returns {Promise} 加载完成的模型对象
   */
  async loadModel(url, matrix) {
    try {
      const tileset = await Cesium.Cesium3DTileset.fromUrl(url);
      tileset.modelMatrix = Cesium.Matrix4.fromArray(matrix);
      this.viewer.scene.primitives.add(tileset);
      this.models.push(tileset);
      return tileset;
    } catch (error) {
      console.error("模型加载失败:", error);
      throw error;
    }
  }

  /**
   * 快速加载模型（低精度优先）
   * @param {string} url 模型URL
   * @param {Array} matrix 模型变换矩阵
   * @returns {Promise} 加载完成的模型对象
   */
  async quickLoadModel(url, matrix) {
    try {
      // 创建更优化的加载配置
      const options = {
        maximumScreenSpaceError: this.preloadMode ? 32 : 16, // 预加载模式下使用更大的屏幕空间误差，减少细节
        maximumMemoryUsage: 512, // 限制内存使用
        immediatelyLoadDesiredLevelOfDetail: this.preloadMode, // 预加载模式下立即加载所需细节级别
        skipLevelOfDetail: this.preloadMode, // 预加载模式下跳过一些LOD级别
        loadSiblings: !this.preloadMode, // 非预加载模式下加载同级瓦片
        dynamicScreenSpaceError: true,
        dynamicScreenSpaceErrorDensity: 0.00278,
        dynamicScreenSpaceErrorFactor: 4.0,
        dynamicScreenSpaceErrorHeightFalloff: 0.25
      };
      
      const tileset = await Cesium.Cesium3DTileset.fromUrl(url, options);
      tileset.modelMatrix = Cesium.Matrix4.fromArray(matrix);
      
      // 根据预加载模式设置附加属性
      if (this.preloadMode) {
        tileset.preloadWhenHidden = true;
        tileset.preferLeaves = true;
        tileset.cullRequestsWhileMoving = false;
        tileset.foveatedTimeDelay = 0;
      }
      
      this.viewer.scene.primitives.add(tileset);
      this.models.push(tileset);
      return tileset;
    } catch (error) {
      console.error("快速模型加载失败:", error);
      throw error;
    }
  }

  /**
   * 切换指定模型的显示状态
   * @param {number} index 模型索引
   * @returns {boolean} 切换后的状态
   */
  toggleModel(index) {
    if (index >= 0 && index < this.models.length) {
      this.models[index].show = !this.models[index].show;
      return this.models[index].show;
    }
    return false;
  }

  /**
   * 切换所有模型的显示状态
   * @param {boolean} visible 可选，指定显示状态
   * @returns {boolean} 切换后的状态
   */
  toggleAllModels(visible) {
    if (this.models.length === 0) return false;

    // 如果未指定状态，则根据第一个模型的状态决定
    const targetVisible =
      visible !== undefined ? visible : !this.models[0].show;

    this.models.forEach((model) => {
      model.show = targetVisible;
    });
    return targetVisible;
  }

  /**
   * 显示所有模型
   * @returns {boolean} 操作是否成功
   */
  showAllModels() {
    if (this.models.length === 0) return false;
    
    this.models.forEach((model) => {
      model.show = true;
    });
    return true;
  }

  /**
   * 隐藏所有模型
   * @returns {boolean} 操作是否成功
   */
  hideAllModels() {
    if (this.models.length === 0) return false;
    
    this.models.forEach((model) => {
      model.show = false;
    });
    return true;
  }

  /**
   * 获取模型数量
   * @returns {number} 模型数量
   */
  getModelCount() {
    return this.models.length;
  }

  /**
   * 获取指定模型的状态
   * @param {number} index 模型索引
   * @returns {boolean} 模型是否可见
   */
  getModelVisibility(index) {
    if (index >= 0 && index < this.models.length) {
      return this.models[index].show;
    }
    return false;
  }

  /**
   * 添加隧道标记到三维地图上
   * @param {Array} tunnels 隧道数据数组
   * @param {Object} options 配置选项
   * @returns {boolean} 操作是否成功
   */
  addTunnelMarkers(tunnels, options = {}) {
    try {
      // 清除之前的隧道标记
      this.clearTunnelMarkers();
      
      if (!tunnels || !tunnels.length) return false;

      const defaultOptions = {
        singleTunnelImageUrl: null, // 将由组件传入
        tunnelGroupImageUrl: null, // 将由组件传入
        labelOffset: new Cesium.Cartesian2(0, -50),
        labelHorizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 默认为居中对齐
        labelVerticalOrigin: Cesium.VerticalOrigin.TOP, // 默认为顶部对齐
        billboardScale: 0.5,
        heightOffset: 300, // 高度偏移，避免标记被地形遮挡
        maxLabelChars: 5, // 默认最大标签字符数
        useCustomRendering: false // 是否使用自定义渲染
      };

      // 合并选项
      const finalOptions = { ...defaultOptions, ...options };
      
      // 用于跟踪已使用的ID，避免重复
      const usedIds = new Set();
      
      // 生成唯一ID
      const generateUniqueId = (prefix, baseId) => {
        let id = `${prefix}-${baseId || Math.random().toString(36).substring(2, 9)}`;
        let counter = 0;
        
        // 如果ID已存在，添加计数器直到找到唯一ID
        while (usedIds.has(id)) {
          counter++;
          id = `${prefix}-${baseId || Math.random().toString(36).substring(2, 9)}-${counter}`;
        }
        
        usedIds.add(id);
        return id;
      };
      
      // 检查是否提供了必要的图片资源
      if (!finalOptions.singleTunnelImageUrl || !finalOptions.tunnelGroupImageUrl) {
        console.error('隧道标记图片资源未提供');
        return false;
      }
      
      // 添加每个隧道的标记
      tunnels.forEach(tunnel => {
        // 确保位置有效
        if (!tunnel.position || !Array.isArray(tunnel.position) || 
            tunnel.position.length < 2 ||
            isNaN(tunnel.position[0]) || isNaN(tunnel.position[1])) {
          console.warn(`隧道 ${tunnel.name || '未命名'} 位置无效:`, tunnel.position);
          return;
        }

        const position = tunnel.position;
        const lng = Number(position[0]);
        const lat = Number(position[1]);
        const height = position[2] ? Number(position[2]) : finalOptions.heightOffset;
        
        // 选择图标
        const imageUrl = tunnel.tunnelType === '隧道群' 
          ? finalOptions.tunnelGroupImageUrl 
          : finalOptions.singleTunnelImageUrl;
          
        // 处理文本，确保适合在盒子内显示
        let labelText = tunnel.name;
        const maxChars = finalOptions.maxLabelChars || 5; // 使用配置的最大显示字符数
        
        // 处理文本，确保不会太长
        if (labelText.length > maxChars) {
          labelText = labelText.substring(0, maxChars) + '..';
        }
        
        // 根据是否使用自定义渲染选择不同的添加方式
        if (finalOptions.useCustomRendering) {
          // 只添加一个billboard实体，不添加单独的label
          const combinedEntity = this.viewer.entities.add({
            position: Cesium.Cartesian3.fromDegrees(lng, lat, height),
            billboard: {
              image: imageUrl,
              scale: finalOptions.billboardScale,
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
              heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
              scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 20000, 0.8)
            },
            // 添加所有需要的属性，以便点击时能正确识别
            tunnel: tunnel,
            name: tunnel.name,
            tunnelId: tunnel.id,
            id: generateUniqueId('tunnel', tunnel.id)
          });
          
          // 将实体添加到隧道实体数组
          this.tunnelEntities.push(combinedEntity);
        } else {
          // 原有的实现方式...
        // 添加标记
        const billboardEntity = this.viewer.entities.add({
          position: Cesium.Cartesian3.fromDegrees(lng, lat, height),
          billboard: {
            image: imageUrl,
            scale: finalOptions.billboardScale,
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            disableDepthTestDistance: Number.POSITIVE_INFINITY, // 确保始终可见，不被地形遮挡
            heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
              scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 20000, 0.8) // 调整缩放参数
          },
          tunnel: tunnel, // 保存隧道数据供点击事件使用
            name: tunnel.name, // 添加名称属性方便查找
            id: generateUniqueId('tunnel', tunnel.id) // 添加唯一ID
        });

        // 添加文本标签
        const labelEntity = this.viewer.entities.add({
          position: Cesium.Cartesian3.fromDegrees(lng, lat, height),
          label: {
              text: labelText,
              font: 'bold 13px Microsoft YaHei', // 调整字体大小
            fillColor: Cesium.Color.WHITE,
            outlineColor: Cesium.Color.BLACK,
              outlineWidth: 2, // 轮廓宽度
            style: Cesium.LabelStyle.FILL_AND_OUTLINE,
              verticalOrigin: finalOptions.labelVerticalOrigin, // 使用传入的对齐参数
              horizontalOrigin: finalOptions.labelHorizontalOrigin, // 使用传入的对齐参数
            pixelOffset: finalOptions.labelOffset,
            heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
              disableDepthTestDistance: Number.POSITIVE_INFINITY, // 确保始终可见
              scaleByDistance: new Cesium.NearFarScalar(1000, 1.2, 20000, 0.8),
              eyeOffset: new Cesium.Cartesian3(0, 0, -10) // 确保标签显示在图标前方
            },
            tunnel: tunnel,
            id: generateUniqueId('tunnelLabel', tunnel.id)
          });

          // 将实体添加到隧道实体数组
        this.tunnelEntities.push(billboardEntity);
        this.tunnelEntities.push(labelEntity);
        }
        
        // 使用Canvas直接在图片上绘制文字
        if (finalOptions.useCustomRendering) {
          try {
            // 创建一个新的图像来合成图标和文字
            const img = new Image();
            img.src = imageUrl;
            img.onload = () => {
              // 创建画布
              const canvas = document.createElement('canvas');
              const width = img.width;
              const height = img.height;
              canvas.width = width;
              canvas.height = height;
              
              // 获取2D上下文
              const ctx = canvas.getContext('2d');
              
              // 绘制原始图像
              ctx.drawImage(img, 0, 0);
              
              // 设置文字样式
              ctx.font = 'bold 13px Microsoft YaHei';
              ctx.fillStyle = 'white';
              ctx.textAlign = 'center';
              ctx.textBaseline = 'middle';
              
              // 计算文本位置 - 根据图片类型判断位置
              // 确保文字位于图片的蓝色方块区域内
              let textX, textY;
              
              // 判断是否是隧道群图标（一般隧道群图标更宽一些）
              const isTunnelGroup = width > height * 1.5;
              
              if (isTunnelGroup) {
                // 隧道群图标，文字放在右侧区域
                textX = width * 0.68;
                textY = height * 0.22; // 上移一点
              } else {
                // 普通隧道图标，文字居中偏右
                textX = width * 0.65;
                textY = height * 0.22; // 上移一点
              }
              
              // 适应文字长度 - 根据文字长度调整字体大小
              const textWidth = ctx.measureText(labelText).width;
              const maxWidth = width * 0.65; // 蓝色框的最大宽度
              
              // 如果文字太长，缩小字体
              if (textWidth > maxWidth) {
                const scaleFactor = maxWidth / textWidth * 0.9; // 留一点边距
                const newFontSize = Math.max(9, Math.floor(13 * scaleFactor)); // 最小不小于9px
                ctx.font = `bold ${newFontSize}px Microsoft YaHei`;
              }
              
              // 优化文字渲染 - 先绘制描边提高可读性
              // 描边使用多次绘制的方式，比单次描边效果更好
              ctx.strokeStyle = 'black';
              ctx.lineWidth = 2;
              
              // 多次绘制文字轮廓，形成更好的描边效果
              for (let i = 0; i < 8; i++) {
                const angle = (i / 8) * Math.PI * 2;
                const offsetX = Math.sin(angle) * 1;
                const offsetY = Math.cos(angle) * 1;
                ctx.strokeText(labelText, textX + offsetX, textY + offsetY);
              }
              
              // 绘制文字
              ctx.fillText(labelText, textX, textY);
              
              // 将合成的图像作为新的实体图像
              const dataURL = canvas.toDataURL();
              
              // 更新实体的图像
              const entity = this.tunnelEntities.find(e => 
                e.tunnel && e.tunnel.id === tunnel.id && e.billboard
              );
              
              if (entity && entity.billboard) {
                entity.billboard.image = dataURL;
              }
            };
          } catch (error) {
            console.error('创建自定义图像失败:', error);
          }
        }
      });

      // 设置点击事件处理
      this.setupTunnelClickHandler();
      
      return true;
    } catch (error) {
      console.error('添加隧道标记失败:', error);
      return false;
    }
  }

  /**
   * 清除所有隧道标记
   */
  clearTunnelMarkers() {
    try {
      console.log('开始清除隧道标记，总数:', this.tunnelEntities.length);
      
      // 删除所有隧道实体
      for (let i = 0; i < this.tunnelEntities.length; i++) {
        const entity = this.tunnelEntities[i];
        if (entity && entity.id) {
          try {
            // 输出要移除的实体ID，以便调试
            console.log('移除实体:', entity.id);
            this.viewer.entities.remove(entity);
          } catch (e) {
            console.warn('移除实体失败:', e.message);
          }
        }
      }
      
      // 直接从实体集合中删除所有以"tunnel-"开头的实体
      const allEntities = this.viewer.entities.values.slice();
      for (let i = 0; i < allEntities.length; i++) {
        const entity = allEntities[i];
        if (entity && entity.id && (
            typeof entity.id === 'string' && 
            (entity.id.startsWith('tunnel-') || entity.id.startsWith('tunnelLabel-'))
          )) {
          try {
            this.viewer.entities.removeById(entity.id);
          } catch (e) {
            console.warn('通过ID移除实体失败:', entity.id, e.message);
          }
        }
      }
      
      // 清空数组
      this.tunnelEntities = [];
      
      // 移除点击事件处理器
      this.removeTunnelClickHandler();
      
      console.log('隧道标记清除完成');
    } catch (error) {
      console.error('清除隧道标记失败:', error);
    }
  }

  /**
   * 设置隧道标记点击事件处理器
   */
  setupTunnelClickHandler() {
    console.log('开始设置点击事件处理器');
    
    // 移除现有处理程序(如果存在)
    this.removeTunnelClickHandler();
    
    try {
      // 创建新的事件处理程序
      this._tunnelClickHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas);
      
      // 处理左键点击
      this._tunnelClickHandler.setInputAction(movement => {
        try {
          console.log('触发点击事件');
          
          // 获取点击位置的对象
          const pickedObject = this.viewer.scene.pick(movement.position);
          console.log('点击事件触发，拾取对象:', pickedObject);
          
          // 记录点击坐标，便于调试
          const cartesian = this.viewer.camera.pickEllipsoid(movement.position);
          if (cartesian) {
            const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
            const lng = Cesium.Math.toDegrees(cartographic.longitude).toFixed(6);
            const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(6);
            console.log(`点击位置坐标: 经度=${lng}, 纬度=${lat}`);
          }
          
          // 如果没有拾取到对象，尝试使用射线拾取
          if (!Cesium.defined(pickedObject)) {
            console.log('未拾取到对象，尝试使用射线拾取');
            
            // 尝试使用简单直接的点击测试
            const pick = this.viewer.scene.drillPick(movement.position);
            if (pick && pick.length > 0) {
              for (let i = 0; i < pick.length; i++) {
                const obj = pick[i];
                if (obj && obj.id && obj.id.tunnel) {
                  console.log('使用drillPick找到隧道:', obj.id.tunnel.name);
                  this.directFlyToTunnel(obj.id.tunnel);
                  return;
                }
              }
            }
            
            // 获取视线射线
            const ray = this.viewer.camera.getPickRay(movement.position);
            if (ray) {
              // 计算射线与地球相交点
              const cartesianPosition = this.viewer.scene.globe.pick(ray, this.viewer.scene);
              if (cartesianPosition) {
                // 查找距离该点最近的隧道
                const closestTunnel = this.findClosestTunnel(cartesianPosition);
                if (closestTunnel) {
                  console.log('找到最近的隧道:', closestTunnel.name);
                  this.directFlyToTunnel(closestTunnel);
                  return;
                }
              }
            }
            
            // 如果上述方法都失败，尝试直接访问所有实体
            if (this.tunnelEntities.length > 0) {
              console.log('尝试查找第一个隧道实体');
              for (let i = 0; i < this.tunnelEntities.length; i++) {
                const entity = this.tunnelEntities[i];
                if (entity && entity.tunnel) {
                  console.log('默认使用第一个找到的隧道:', entity.tunnel.name);
                  this.directFlyToTunnel(entity.tunnel);
                  return;
                }
              }
            }
            
            return;
          }
          
          // 确保获取到了有效的对象
          if (!pickedObject.id) {
            console.log('拾取到对象但没有ID');
            return;
          }
          
          console.log('拾取到的对象ID:', pickedObject.id.id);
          
          // 查找隧道数据
          let tunnel = null;
          
          // 1. 直接从id对象中获取tunnel属性
          if (pickedObject.id.tunnel) {
            tunnel = pickedObject.id.tunnel;
            console.log('从实体直接获取隧道数据:', tunnel.name);
          }
          // 2. 通过id字符串查找对应的隧道
          else if (typeof pickedObject.id.id === 'string') {
            const idString = pickedObject.id.id;
            console.log('实体ID:', idString);
            
            if (idString.startsWith('tunnel-') || idString.startsWith('tunnelLabel-')) {
              // 从ID字符串中提取隧道ID
              const tunnelId = idString
                .replace(/^tunnel-/, '')
                .replace(/^tunnelLabel-/, '')
                .split('-')[0]; // 获取第一部分作为ID
              
              console.log('提取的隧道ID:', tunnelId);
              
              // 在实体集合中查找匹配的实体
              for (let i = 0; i < this.tunnelEntities.length; i++) {
                const entity = this.tunnelEntities[i];
                if (entity && entity.tunnel) {
                  const entityTunnelId = entity.tunnel.id ? entity.tunnel.id.toString() : '';
                  if (entityTunnelId === tunnelId || entity.id === pickedObject.id.id) {
                    tunnel = entity.tunnel;
                    console.log('通过ID匹配找到隧道:', tunnel.name);
                    break;
                  }
                }
              }
            }
          }
          // 3. 通过名称查找
          else if (pickedObject.id.name) {
            const name = pickedObject.id.name;
            console.log('尝试通过名称查找隧道:', name);
            
            for (let i = 0; i < this.tunnelEntities.length; i++) {
              const entity = this.tunnelEntities[i];
              if (entity && entity.tunnel && entity.tunnel.name === name) {
                tunnel = entity.tunnel;
                console.log('通过名称找到隧道:', tunnel.name);
                break;
              }
            }
          }
          
          // 如果找到了隧道数据，执行飞行
          if (tunnel) {
            console.log('准备飞行到隧道:', tunnel.name);
            // 使用直接飞行方法而非过渡动画
            this.directFlyToTunnel(tunnel);
          } else {
            console.warn('未能识别点击的实体');
          }
        } catch (error) {
          console.error('处理点击事件时发生错误:', error);
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
      
      console.log('隧道点击事件处理器已设置完成');
    } catch (error) {
      console.error('设置点击事件处理器失败:', error);
    }
  }

  /**
   * 移除隧道标记点击事件处理器
   */
  removeTunnelClickHandler() {
    if (this._tunnelClickHandler) {
      this._tunnelClickHandler.destroy();
      this._tunnelClickHandler = null;
    }
  }

  /**
   * 查找距离指定位置最近的隧道
   * @param {Cesium.Cartesian3} position 位置
   * @returns {Object|null} 最近的隧道
   */
  findClosestTunnel(position) {
    if (!position || this.tunnelEntities.length === 0) return null;
    
    try {
      let closestTunnel = null;
      let minDistance = Number.MAX_VALUE;
      
      // 将位置转换为经纬度
      const cartographic = Cesium.Cartographic.fromCartesian(position);
      const lng = Cesium.Math.toDegrees(cartographic.longitude);
      const lat = Cesium.Math.toDegrees(cartographic.latitude);
      
      // 遍历所有隧道实体
      for (let i = 0; i < this.tunnelEntities.length; i++) {
        const entity = this.tunnelEntities[i];
        if (!entity.tunnel || !entity.position) continue;
        
        // 获取隧道位置
        const tunnelPos = entity.position.getValue(Cesium.JulianDate.now());
        if (!tunnelPos) continue;
        
        const tunnelCartographic = Cesium.Cartographic.fromCartesian(tunnelPos);
        const tunnelLng = Cesium.Math.toDegrees(tunnelCartographic.longitude);
        const tunnelLat = Cesium.Math.toDegrees(tunnelCartographic.latitude);
        
        // 计算距离（简单使用欧氏距离）
        const distance = Math.sqrt(
          Math.pow(lng - tunnelLng, 2) + 
          Math.pow(lat - tunnelLat, 2)
        );
        
        if (distance < minDistance) {
          minDistance = distance;
          closestTunnel = entity.tunnel;
        }
      }
      
      return closestTunnel;
    } catch (error) {
      console.error('查找最近隧道时出错:', error);
      return null;
    }
  }
  
  /**
   * 直接飞行到隧道位置(不使用动画)
   */
  directFlyToTunnel(tunnel) {
    if (!tunnel) {
      console.error('隧道数据为空');
      return false;
    }
    
    try {
      console.log('执行直接飞行，隧道数据:', tunnel);
      
      // 尝试多种方式获取隧道位置
      let lng, lat, height;
      
      // 方式1: 从 position 数组获取
      if (tunnel.position && Array.isArray(tunnel.position) && tunnel.position.length >= 2) {
        lng = Number(tunnel.position[0]);
        lat = Number(tunnel.position[1]);
        height = tunnel.position.length > 2 ? Number(tunnel.position[2]) : 300;
        console.log('从position数组获取位置:', lng, lat, height);
      }
      // 方式2: 从单独的 lng、lat 属性获取
      else if (tunnel.lng !== undefined && tunnel.lat !== undefined) {
        lng = Number(tunnel.lng);
        lat = Number(tunnel.lat);
        height = tunnel.height !== undefined ? Number(tunnel.height) : 300;
        console.log('从lng/lat属性获取位置:', lng, lat, height);
      }
      // 方式3: 从 longitude、latitude 属性获取
      else if (tunnel.longitude !== undefined && tunnel.latitude !== undefined) {
        lng = Number(tunnel.longitude);
        lat = Number(tunnel.latitude);
        height = tunnel.altitude !== undefined ? Number(tunnel.altitude) : 300;
        console.log('从longitude/latitude属性获取位置:', lng, lat, height);
      }
      // 如果都没找到，返回错误
      else {
        console.error('无法获取隧道位置信息:', tunnel);
        return false;
      }
      
      // 检查经纬度有效性
      if (isNaN(lng) || isNaN(lat) || !isFinite(lng) || !isFinite(lat)) {
        console.error('无效的经纬度:', lng, lat);
        return false;
      }
      
      // 设置更高的高度，防止无卫星图问题
      const viewHeight = 2500; // 增加到2500米
      
      // 设置偏移量，使视角稍微向上，能直接看到隧道标记
      const offsetLat = -0.0502; // 纬度偏移，使视角略微向上
      
      // 尝试多种方式移动相机
      console.log('正在移动相机到:', lng, lat + offsetLat, viewHeight);
      
      try {
        // 方法1: 使用flyTo
        this.viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(lng, lat + offsetLat, viewHeight),
          orientation: {
            heading: 0,
            pitch: Cesium.Math.toRadians(-30), // 调整俯仰角度为-30度，更平缓一些
            roll: 0
          },
          duration: 1.0, // 快速飞行
          complete: () => {
            console.log('相机飞行完成');
            this.highlightTunnel(tunnel);
          }
        });
      } catch (e) {
        console.warn('flyTo失败，尝试直接设置相机:', e.message);
        
        try {
          // 方法2: 使用setView
          this.viewer.camera.setView({
            destination: Cesium.Cartesian3.fromDegrees(lng, lat + offsetLat, viewHeight),
            orientation: {
              heading: 0,
              pitch: Cesium.Math.toRadians(-30), // 调整俯仰角度为-30度
              roll: 0
            }
          });
          
          console.log('setView完成');
          this.highlightTunnel(tunnel);
        } catch (e2) {
          console.warn('setView失败，尝试直接设置属性:', e2.message);
          
          try {
            // 方法3: 直接设置相机属性
            const destination = Cesium.Cartesian3.fromDegrees(lng, lat + offsetLat, viewHeight);
            this.viewer.camera.position = destination;
            this.viewer.camera.heading = 0;
            this.viewer.camera.pitch = Cesium.Math.toRadians(-30); // 调整俯仰角度为-30度
            this.viewer.camera.roll = 0;
            
            console.log('直接设置相机属性完成');
            this.highlightTunnel(tunnel);
          } catch (e3) {
            console.error('所有移动相机方法都失败:', e3.message);
            return false;
          }
        }
      }
      
      // 检查移动结果
      setTimeout(() => {
        const pos = this.viewer.camera.positionCartographic;
        console.log('移动后的相机位置:', 
          Cesium.Math.toDegrees(pos.longitude).toFixed(5),
          Cesium.Math.toDegrees(pos.latitude).toFixed(5),
          pos.height.toFixed(0)
        );
      }, 1500);
      
      return true;
    } catch (error) {
      console.error('直接飞行到隧道失败:', error);
      return false;
    }
  }

  /**
   * 高亮显示选中的隧道
   * @param {Object} tunnel 隧道数据对象
   */
  highlightTunnel(tunnel) {
    try {
      if (!tunnel || (!tunnel.id && !tunnel.name)) {
        console.warn('无效的隧道数据:', tunnel);
        return;
      }
      
      console.log('尝试高亮显示隧道:', tunnel.name || tunnel.id);
      
      // 查找匹配的实体
      let matchingEntity = null;
      
      // 1. 先通过ID精确匹配
      if (tunnel.id) {
        // 在所有实体中查找
        const allEntities = this.viewer.entities.values;
        for (let i = 0; i < allEntities.length; i++) {
          const entity = allEntities[i];
          if (entity.billboard && entity.tunnel && entity.tunnel.id === tunnel.id) {
            matchingEntity = entity;
            console.log('通过ID精确匹配找到实体');
            break;
          }
        }
      }
      
      // 2. 如果未找到，通过名称匹配
      if (!matchingEntity && tunnel.name) {
        const allEntities = this.viewer.entities.values;
        for (let i = 0; i < allEntities.length; i++) {
          const entity = allEntities[i];
          if (entity.billboard && entity.tunnel && entity.tunnel.name === tunnel.name) {
            matchingEntity = entity;
            console.log('通过名称匹配找到实体');
            break;
          }
        }
      }
      
      // 3. 如果仍未找到，通过位置匹配
      if (!matchingEntity && tunnel.position && Array.isArray(tunnel.position)) {
        const targetPos = tunnel.position;
        const allEntities = this.viewer.entities.values;
        
        for (let i = 0; i < allEntities.length; i++) {
          const entity = allEntities[i];
          if (!entity.position || !entity.billboard) continue;
          
          // 获取实体的位置
          const entityPos = entity.position.getValue(Cesium.JulianDate.now());
          if (!entityPos) continue;
          
          const cartographic = Cesium.Cartographic.fromCartesian(entityPos);
          const entityLng = Cesium.Math.toDegrees(cartographic.longitude);
          const entityLat = Cesium.Math.toDegrees(cartographic.latitude);
          
          // 比较位置是否接近（0.01度约等于1公里）
          if (Math.abs(entityLng - targetPos[0]) < 0.01 && Math.abs(entityLat - targetPos[1]) < 0.01) {
            matchingEntity = entity;
            console.log('通过位置匹配找到实体');
            break;
          }
        }
      }
      
      if (matchingEntity) {
        console.log('找到匹配的隧道实体，创建闪烁效果');
        
        // 创建闪烁效果
        let blinkCount = 0;
        const maxBlinks = 8;
        const originalScale = matchingEntity.billboard.scale._value || 0.8;
        const largerScale = originalScale * 1.8;
        
        // 停止之前的闪烁效果（如果有）
        if (this._currentBlinkInterval) {
          clearInterval(this._currentBlinkInterval);
          this._currentBlinkInterval = null;
        }
        
        // 先立即放大
        matchingEntity.billboard.scale = largerScale;
        
        this._currentBlinkInterval = setInterval(() => {
          try {
            if (blinkCount >= maxBlinks || !matchingEntity.billboard) {
              clearInterval(this._currentBlinkInterval);
              this._currentBlinkInterval = null;
              if (matchingEntity.billboard) {
                matchingEntity.billboard.scale = originalScale;
              }
              return;
            }
            
            // 交替缩放大小
            matchingEntity.billboard.scale = (blinkCount % 2 === 0) ? largerScale : originalScale;
            blinkCount++;
          } catch (error) {
            console.error('闪烁效果应用失败:', error);
            clearInterval(this._currentBlinkInterval);
            this._currentBlinkInterval = null;
          }
        }, 200); // 更快的闪烁频率
      } else {
        console.warn('未找到匹配的隧道实体，无法高亮显示', tunnel);
      }
    } catch (error) {
      console.error('高亮显示隧道时发生错误:', error);
    }
  }
}
